package designpatterns.structure;

/**
 * 桥接模式
 * 将抽象与实现分离，使它们可以独立变化。它是用组合关系代替继承关系来实现，从而降低了抽象和实现这两个可变维度的耦合度。
 * 使用场景：1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性，避免在两个层次之间建立静态的继承联系，
 * 通过桥接模式可以使它们在抽象层建立一个关联关系。
 * 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统，桥接模式尤为适用。
 * 3、一个类存在两个独立变化的维度，且这两个维度都需要进行扩展。
 * 优点：抽象和实现的分离、实现细节对客户透明、优秀的扩展能力
 * 缺点：桥接模式的引入会增加系统的理解与设计难度，由于聚合关联关系建立在抽象层，要求开发者针对抽象进行设计与编程。
 *
 * @author jack.wu
 * @since 2019/9/20
 */
public class BridgeTest {

    public static void main(String[] args) {
        AbstractShape redCircle = new Circle(new RedCircle(), 5);
        AbstractShape greenCircle = new Circle(new GreenCircle(), 5);
        redCircle.draw();
        greenCircle.draw();
    }

}

interface DrawApi {

    /**
     * 画圆
     *
     * @param radius 半径
     */
    void drawCircle(int radius);
}

class RedCircle implements DrawApi {

    @Override
    public void drawCircle(int radius) {
        System.out.println("Draw Circle[color : red,radius : " + radius + "]");
    }
}

class GreenCircle implements DrawApi {

    @Override
    public void drawCircle(int radius) {
        System.out.println("Draw Circle[color : green,radius : " + radius + "]");
    }
}

abstract class AbstractShape {

    protected DrawApi drawApi;

    protected AbstractShape(DrawApi drawApi) {
        this.drawApi = drawApi;
    }

    public abstract void draw();

}

class Circle extends AbstractShape {

    private int radius;

    protected Circle(DrawApi drawApi, int radius) {
        super(drawApi);
        this.radius = radius;
    }

    @Override
    public void draw() {
        drawApi.drawCircle(radius);
    }
}
